package com.mimiwang.user.controller;

import com.google.code.kaptcha.Producer;
import com.mimiwang.common.exception.BizCodeEnum;
import com.mimiwang.common.group.Insert;
import com.mimiwang.common.utils.PageUtils;
import com.mimiwang.common.utils.R;
import com.mimiwang.common.utils.ResponseUtil;
import com.mimiwang.common.utils.TokenUtil;
import com.mimiwang.user.entity.UserInfoEntity;
import com.mimiwang.user.entity.vo.LoginByEmailEntity;
import com.mimiwang.user.entity.vo.LoginByMobileEntity;
import com.mimiwang.user.entity.vo.LoginByPasswordEntity;
import com.mimiwang.user.exception.NullValidateCodeException;
import com.mimiwang.user.exception.ValidateCodeErrorException;
import com.mimiwang.user.service.UserInfoService;
import com.mimiwang.user.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.imageio.ImageIO;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Map;


/**
 * @author hustart
 * @email hustart1@126.com
 * @date 2022-09-30 22:24:17
 */
@RestController
@RequestMapping("/user")
@Api("用户信息Api")
@Slf4j
public class UserInfoController {
    @Autowired
    private UserInfoService userInfoService;



    /**
     * 列表
     */

    @ApiOperation("获取用户信息")
    @PostMapping("/list")
    public R list(@RequestParam Map<String, Object> params) {
        PageUtils page = userInfoService.queryPage(params);

        return R.ok().put("page", page);
    }


    /**
     * 信息
     */
    @GetMapping("/info")
    public String info(HttpServletRequest request) {
        String token = request.getHeader("token");
        String verify = TokenUtil.verify(token);
        long userId=Long.parseLong(verify);

        UserInfoEntity userInfo = userInfoService.getById(userId);

        return ResponseUtil.successJSONData(userInfo);
    }
    @GetMapping("/info/{id}")
    public String info(@PathVariable("id") long id) {


        UserInfoEntity userInfo = userInfoService.getById(id);

        return ResponseUtil.successJSONData(userInfo);
    }
    /**
     * 保存
     */
    @PostMapping("/save")
    public R save(@RequestBody @Validated({Insert.class}) UserInfoEntity userInfo) {
        userInfoService.save(userInfo);

        return R.ok();
    }

    /**
     * 修改
     */
    @PostMapping("/update")
    public R update(@RequestBody UserInfoEntity userInfo) {
        userInfoService.updateById(userInfo);

        return R.ok();
    }

    /**
     * 删除,通过传userId
     */
    @DeleteMapping("/delete")
    public R delete(@RequestBody Long[] userIds) {
        userInfoService.removeByIds(Arrays.asList(userIds));

        return R.ok();
    }


    /**
     * 查询用户名在数据库中是否存在
     */
    @GetMapping("/isExistedUserName")
    public R isExistedUserName(String userName) {

        boolean existedUserName = userInfoService.isExistedUserName(userName);
        if (existedUserName) {
            return R.ok().put("msg", "用户名可用");
        }
        return R.error(BizCodeEnum.USERNAME_EXIST.getCode(), BizCodeEnum.USERNAME_EXIST.getMsg());
    }

    /**
     * @description 判断手机号是否被注册
     * @param mobile
     * @return
     */

    @GetMapping("/isExistedMobile")
    public R isExistedMobile(String mobile) {

        boolean existedMobile = userInfoService.isExistedMobile(mobile);
        if (existedMobile) {
            return R.ok().put("msg", "手机号未被注册");
        }

        return R.error(BizCodeEnum.MOBILE_EXIST.getCode(), BizCodeEnum.MOBILE_EXIST.getMsg());
    }


    /**
     * 注册
     */
    @RequestMapping("/register")
    public R register(@RequestBody @Validated(Insert.class) UserInfoEntity userInfoEntity, String code) {

        boolean isRegisted = userInfoService.register(code, userInfoEntity);
        if (isRegisted) {
            return R.ok("注册成功");
        }
        return R.error(BizCodeEnum.VERIFICATION_CODE_ERROR.getCode(), BizCodeEnum.VERIFICATION_CODE_ERROR.getMsg());
    }


    /**
     * 获取手机验证码
     */

    @RequestMapping("/securityCode")
    public R getSecurityCode(String mobile) {


        userInfoService.sendSecurityCode(mobile);


        return R.ok();
    }




    /**
     * 账号密码登录
     * 返回token存储在cookies中
     */
    @PostMapping("/loginByPassword")
    public R loginByPassword(@RequestBody LoginByPasswordEntity entity, HttpSession session, HttpServletRequest request,
                             HttpServletResponse response) {


        // 如果密码错误次数超出五次，则限制登录
        boolean isIncorrect = userInfoService.checkLoginIncorrect(request);
        if(isIncorrect){
            return R.error(BizCodeEnum.PASSWORD_INCORRECT_OVERRUN.getCode(),BizCodeEnum.PASSWORD_INCORRECT_OVERRUN.getMsg());
        }

        String userName = entity.getUserName();
        String password = entity.getPassword();
        String kaptcha = entity.getKaptchaCode();

        String expectKaptchaCode = (String)session.getAttribute("kaptcha");
        // 验证参数是否有空值
        if(userName == null || password == null || kaptcha == null ) {
            return R.error(BizCodeEnum.PARAM_IS_NULL.getCode(),BizCodeEnum.PARAM_IS_NULL.getMsg());
        }
        // 获取userId
        Long userId = userInfoService.selectByUserName(userName);
        //检查验证码是否为空
        if(expectKaptchaCode == null){
            return R.error(BizCodeEnum.VERIFICATION_CODE_ERROR.getCode(),BizCodeEnum.VERIFICATION_CODE_ERROR.getMsg());
        } else {
            boolean verify = kaptcha.equalsIgnoreCase(expectKaptchaCode);
            // 测试
            if(!verify) {
                return R.error(BizCodeEnum.VERIFICATION_CODE_ERROR.getCode(),BizCodeEnum.VERIFICATION_CODE_ERROR.getMsg());
            }
        }

        int i = userInfoService.verifyUserInfo(userName, password,request);
        if(i == 0){
            return R.error(BizCodeEnum.USER_NOT_EXIST.getCode(),BizCodeEnum.USER_NOT_EXIST.getMsg());
        } else if(i == 1){
            return R.error(BizCodeEnum.USER_PASSWORD_ERROR.getCode(),BizCodeEnum.USER_PASSWORD_ERROR.getMsg());
        }
        String token = userInfoService.distributeToken(userId, userName);
        response.addCookie(new Cookie("token",token));

        return R.ok().put("msg","登录成功");
    }


    @PostMapping("/loginByMobile")
    public R loginByMobile(@RequestBody LoginByMobileEntity entity, HttpServletResponse response){
        //获取手机号
        String mobile = entity.getMobile();
        //获取验证码
        String verifyCode = entity.getVerifyCode();
        /**
         * 如果手机号或者验证码传空提示用户重传
         */
        if(mobile == null || verifyCode == null ){
            return R.error(BizCodeEnum.PARAM_IS_NULL.getCode(),BizCodeEnum.PARAM_IS_NULL.getMsg());
        }
        // 检验手机号是否已经注册,未注册返回true,注册了返回false
        boolean existedMobile = userInfoService.isExistedMobile(mobile);

        if(existedMobile){
            return R.error(BizCodeEnum.MOBILE_NOT_EXIST.getCode(),BizCodeEnum.MOBILE_NOT_EXIST.getMsg());
        }

        boolean verify = userInfoService.verifyMobileVerify(mobile, verifyCode);
        if(verify){
            UserInfoEntity userInfoEntity = userInfoService.selectByMobile(mobile);
            String token = userInfoService.distributeToken(userInfoEntity.getUserId(), userInfoEntity.getUserName());
            response.addCookie(new Cookie("token",token));
            return R.ok().put("msg","手机号和验证码匹配,登录成功");
        }

        // 提示错误信息，让用户重新输入
        return R.error(BizCodeEnum.VERIFICATION_CODE_ERROR.getCode(),BizCodeEnum.VERIFICATION_CODE_ERROR.getMsg());

    }

    @Autowired
    UserService userService;

    @PostMapping("/login/email")
    String loginByEmail(@RequestBody LoginByEmailEntity login){
        String email = login.getEmail();
        String code = login.getCode();
        if( email == null){
            return ResponseUtil.errorJSONData("邮箱为空");
        }
        if(code == null){
            return ResponseUtil.errorJSONData("验证码为空");
        }
        try {
            String token = userService.loginByEmail(email, code);
            return ResponseUtil.successJSONData("登录成功",token);
        }catch (NullValidateCodeException e){

            return ResponseUtil.errorJSONData("请先请求验证码");
        }catch (ValidateCodeErrorException error){
            return ResponseUtil.errorJSONData("验证码错误");
        }catch (Exception e){
            e.printStackTrace();
            return ResponseUtil.errorJSONData("服务器出错了");

        }

    }

    @Autowired
    Producer kaptchaProducer;


    @GetMapping("/kaptcha")
    public void getKaptcha(HttpServletResponse response, HttpSession session) {
        // 生成验证码
        String text = kaptchaProducer.createText();
        BufferedImage image = kaptchaProducer.createImage(text);

        // 将验证码存入session
        session.setAttribute("kaptcha", text);

        // 将图片输出给浏览器
        // 声明给浏览器返回的是什么格式的数据
        response.setContentType("image/png");
        try {
            ServletOutputStream os = response.getOutputStream();
            ImageIO.write(image, "png", os);
        } catch (IOException e) {
            log.error("验证码获取失败");
            e.printStackTrace();
        }
    }



    @GetMapping("/getUserInfoByUserId")
    public R getUserInfoByUserId(Long userId) {

        UserInfoEntity userInfoEntity = userInfoService.getUserInfoByUserId(userId);

        return R.ok().put("userInfoEntity",userInfoEntity);
    }





}
